﻿using System;
using System.Collections.Generic;
using DataService.Enums;
using DataService.Structs;

namespace DataService;

public abstract class ConditionBase : IEvent, IDisposable, IComparable<ConditionBase>, IEquatable<ConditionBase>
{
    public const string ALARMSTOP = "Alarm Clear";
    protected bool _enable, _ack, _active;
    protected int _id;
    protected DateTime _timeStamp;
    protected SubAlarmType _tempType;
    protected SubCondition[] _subConditions;

    public int ID
    {
        get
        {
            return _id;
        }
        set
        {
            _id = value;
        }
    }

    public bool IsEnabled
    {
        get
        {
            return _enable;
        }
        set
        {
            _enable = value;
        }
    }

    public bool IsActived
    {
        get
        {
            return _active;
        }
        set
        {
            _active = value;
        }
    }

    public bool IsAcked
    {
        get
        {
            return _ack;
        }
        set
        {
            _ack = value;
            if (_ack)
            {
                _tempType = SubAlarmType.None;
                _lastAckTime = DateTime.Now;
                if (_ack && AlarmAck != null)
                {
                    foreach (EventHandler deleg in AlarmAck.GetInvocationList())
                    {
                        deleg.BeginInvoke(this, EventArgs.Empty, null, null);
                    }
                }
            }
        }
    }

    public abstract AlarmType AlarmType
    {
        get;
    }

    public EventType EventType
    {
        get
        {
            return EventType.ConditionEvent;
        }
    }


    protected ConditionType _conditionType;
    public ConditionType ConditionType
    {
        get
        {
            return _conditionType;
        }
        set
        {
            _conditionType = value;
        }
    }

    protected DateTime _lastAckTime, _condLastActive, _lastInactive;
    public DateTime LastAckTime
    {
        get
        {
            return _lastAckTime;
        }
        set
        {
            _lastAckTime = value;
        }
    }

    public DateTime SubCondLastActive
    {
        get
        {
            return _current.StartTime;
        }
        //set
        //{
        //    _subCondLastActive = value;
        //}
    }

    public DateTime LastActive
    {
        get
        {
            return _condLastActive;
        }
        set
        {
            _condLastActive = value;
        }
    }

    public DateTime LastInactive
    {
        get
        {
            return _lastInactive;
        }
        set
        {
            _lastInactive = value;
        }
    }

    protected AlarmItem _current;

    protected SubAlarmType _activeSub;
    public SubAlarmType ActiveSubCondition
    {
        get
        {
            return _activeSub;
        }
        protected set
        {
            _activeSub = value;
        }
    }

    public Severity Severity
    {
        get
        {
            return _current.Severity;
        }
    }

    public string Message
    {
        get
        {
            return _current.AlarmText;
        }
    }

    public abstract string Value
    {
        get;
    }

    protected float _para;
    public float Para
    {
        get
        {
            return _para;
        }
        set
        {
            _para = value;
        }
    }

    protected float _deadBand;
    public float DeadBand
    {
        get
        {
            return _deadBand;
        }
        set
        {
            _deadBand = value;
        }
    }

    protected int _delay;
    public int Delay
    {
        get
        {
            return _delay;
        }
        set
        {
            _delay = value;
        }
    }

    protected string _comment;
    public string Comment
    {
        get
        {
            return _comment;
        }
        set
        {
            _comment = value;
        }
    }

    protected string _source;
    public string Source
    {
        get
        {
            return _source;
        }
    }

    public IList<SubCondition> SubConditions
    {
        get
        {
            return _subConditions;
        }
    }

    public AlarmEventHandler AlarmActive;
    public EventHandler AlarmAck;

    protected ConditionBase(int id, ConditionType conditionType, string source, string comment, float para, float deadBand, int delay)
    {
        this._id = id;
        this._conditionType = conditionType;
        this._para = para;
        this._source = source;
        this._comment = comment;
        this._deadBand = deadBand;
        this._delay = delay;
        this._current = new AlarmItem();
    }

    public abstract bool AddSubCondition(SubCondition condition);

    public abstract bool RemoveSubCondition(SubCondition condition);

    protected abstract void OnActive(SubCondition condition, Storage value, DateTime timeStamp);

    protected abstract void OnInActive(Storage value);

    public int CompareTo(ConditionBase other)
    {
        int comp1 = ((int)this.Severity).CompareTo((int)other.Severity);
        return comp1 == 0 ? this.LastActive.CompareTo(other.LastActive) : -comp1;
    }

    public bool Equals(ConditionBase other)
    {
        if (other == null) return false;
        return this._id == other._id;
    }

    public virtual void Dispose()
    {
        _current = null;
        AlarmAck = null;
        AlarmActive = null; ;
    }
}
